package adapletplugin.editors;

import objects.Relationship;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;

import adapletplugin.dialogs.NewAttributeDialog;

public class RelEditor extends AbstractSubEditor
{
	private Text fRelNameText;
	private Text fTableNameText;
	private Text fIdColText;
	// private Button fIdIsMappedBox;
	private Text fDefaultTypeText;
	private Text fFromTypeText;
	private Text fFromIdColText;
	private Text fToTypeText;
	private Text fToIdColText;
	private Relationship relFocusObject;

	private Button fNewAttributeButton;
	private TableViewer fAttributeTable;

	public RelEditor(ScrolledComposite composite, FormToolkit toolkit, MapFileEditor parentEditor)
	{
		super(composite, toolkit, parentEditor);
	}

	@Override
	protected void create()
	{
		Composite row = fToolkit.createComposite(fSubComposite);
		row.setLayout(new GridLayout(2, false));
		row.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

		fToolkit.createLabel(row, "Relationship Name:");
		fRelNameText = fToolkit.createText(row, "", SWT.BORDER | SWT.READ_ONLY);
		fRelNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fRelNameText.addModifyListener(createModifyListener_Name());

		fToolkit.createLabel(row, "Table Name:");
		fTableNameText = fToolkit.createText(row, "", SWT.BORDER);
		fTableNameText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fTableNameText.addModifyListener(createModifyListener_Table());

		fToolkit.createLabel(row, "ID Column:");
		fIdColText = fToolkit.createText(row, "", SWT.BORDER);
		fIdColText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fIdColText.addModifyListener(createModifyListener_ID());

		fToolkit.createLabel(row, "Default Type:");
		fDefaultTypeText = fToolkit.createText(row, "", SWT.BORDER);
		fDefaultTypeText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fDefaultTypeText.addModifyListener(createModifyListener_Default());

		fToolkit.createLabel(row, "From Type:");
		fFromTypeText = fToolkit.createText(row, "", SWT.BORDER);
		fFromTypeText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fFromTypeText.addModifyListener(createModifyListener_FromType());

		fToolkit.createLabel(row, "From ID Column:");
		fFromIdColText = fToolkit.createText(row, "", SWT.BORDER);
		fFromIdColText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fFromIdColText.addModifyListener(createModifyListener_FromId());

		fToolkit.createLabel(row, "To Type:");
		fToTypeText = fToolkit.createText(row, "", SWT.BORDER);
		fToTypeText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fToTypeText.addModifyListener(createModifyListener_ToType());

		fToolkit.createLabel(row, "To ID Column:");
		fToIdColText = fToolkit.createText(row, "", SWT.BORDER);
		fToIdColText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		fToIdColText.addModifyListener(createModifyListener_ToId());

		fNewAttributeButton = fToolkit.createButton(fSubComposite, "Add Attribute", SWT.PUSH);
		fNewAttributeButton.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false));
		fNewAttributeButton.addSelectionListener(createNewAttributeListener());

		fAttributeTable = new TableViewer(fSubComposite, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
		fAttributeTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		fAttributeTable.setContentProvider(new AttributeTableContentProvider());
		fAttributeTable.setLabelProvider(new AttributeTableLabelProvider());

		TableColumn col = new TableColumn(fAttributeTable.getTable(), SWT.LEFT);
		col.setMoveable(false);
		col.setResizable(true);
		col.setText("Attribute");
		col.setWidth(100);

		col = new TableColumn(fAttributeTable.getTable(), SWT.RIGHT);
		col.setMoveable(false);
		col.setResizable(true);
		col.setText("Table Column");
		col.setWidth(100);

		fAttributeTable.getTable().setHeaderVisible(true);

		fAttributeTable.setInput(new AttributeTableInput(relFocusObject));
	}

	private SelectionListener createNewAttributeListener()
	{
		return new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e)
			{
				Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();

				NewAttributeDialog dialog = new NewAttributeDialog(shell);

				dialog.create();
				dialog.open();

				if (dialog.getReturnCode() == Window.OK)
				{
					relFocusObject.addAttribute(dialog.getAttribute(), dialog.getColumn());

					fAttributeTable.refresh();
					fEditor.refresh();
				}
			}
		};
	}

	private ModifyListener createModifyListener_Name()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setRelationshipName(fRelNameText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_Table()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setTableName(fTableNameText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_ID()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setId(fIdColText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_Default()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setDefaultType(fDefaultTypeText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_FromType()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setFromType(fFromTypeText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_FromId()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setFromId(fFromIdColText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_ToType()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setToType(fToTypeText.getText());
				fEditor.refresh();
			}
		};
	}

	private ModifyListener createModifyListener_ToId()
	{
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent e)
			{
				relFocusObject.setToId(fToIdColText.getText());
				fEditor.refresh();
			}
		};
	}

	@Override
	protected void updateFields()
	{
		relFocusObject = (Relationship) fFocusObject;

		fRelNameText.setText(relFocusObject.getRelationshipName());
		fTableNameText.setText(relFocusObject.getTableName());
		fIdColText.setText(relFocusObject.getId());
		fDefaultTypeText.setText(relFocusObject.getDefaultType());
		fFromTypeText.setText(relFocusObject.getFromType());
		fFromIdColText.setText(relFocusObject.getFromId());
		fToTypeText.setText(relFocusObject.getToType());
		fToIdColText.setText(relFocusObject.getToId());

		fAttributeTable.setInput(new AttributeTableInput(relFocusObject));
	}

	private class AttributeTableContentProvider implements IStructuredContentProvider
	{

		@Override
		public void dispose()
		{

		}

		@Override
		public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
		{

		}

		@Override
		public Object[] getElements(Object inputElement)
		{
			return ((AttributeTableInput) inputElement).getData();
		}

	}

	private class AttributeTableLabelProvider extends LabelProvider implements ITableLabelProvider
	{

		@Override
		public Image getColumnImage(Object element, int columnIndex)
		{
			return null;
		}

		@Override
		public String getColumnText(Object element, int columnIndex)
		{
			if (columnIndex == 0)
			{
				return (String) element;
			}
			else if (columnIndex == 1)
			{
				return relFocusObject.getAttributeColumn((String) element);
			}
			else
			{
				return "INVALID COLUMN";
			}
		}

	}

	private class AttributeTableInput
	{
		private Relationship fInput;

		public AttributeTableInput(Relationship relationship)
		{
			fInput = relationship;
		}

		public String[] getData()
		{
			if (fInput == null)
			{
				return new String[0];
			}
			return fInput.getAttributeNames();

		}
	}

}
